﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Krile.Kernel;
using Krile.Common;
using Mixture.Data;
using System.Net;
using System.Text.RegularExpressions;
using Mixture.Common;

namespace Mixture.IronMixi
{
    /// <summary>
    /// Mixi api wrapper
    /// </summary>
    public static class MixiApi
    {
        public static NetConnect nc = new NetConnect();
        public static bool GetCookie(Account a)
        {
            var req = nc.CreateRequest(new Uri("http://mixi.jp/login.pl"), false);
            var send = new Dictionary<string, string>();
            send.Add("next_url", "/home.pl");
            send.Add("email", a.Id);
            send.Add("password", a.PasswordRaw);
            a.CookieContainer = new System.Net.CookieContainer();
            req.CookieContainer = a.CookieContainer;

            var r = nc.WebFormSendString(
                req,
                send,
                Encoding.ASCII);
            return r.Succeeded;
        }

        public enum TimelineTypes { Timeline, MyVoice, Replies };

        private static Regex mixiAnalyzer = new Regex(
@"\<tr class=\""(?:odd|even)\""\>
\<td class=\""thumb\""\>.*?\<img src=\""(?<Icon>.*?)\"".*?\/\>.*?\<\/td\>
.*?
\<td class=\""comment\""\>.*?\<span\>\<a href=\""(?<Permalink>.*?)\""\>.*?
\<div class=\""echo_member_id\"".*?>(?<UserId>.*?)\<\/div\>
\<div class=\""echo_post_time\"".*?>(?<CreatedAt>.*?)\<\/div\>
\<div class=\""echo_nickname\"".*?>(?<UserName>.*?)\<\/div\>
\<div class=\""echo_body\"".*?>(?<Body>.*?)\<\/div\>.*?
\<\/td\>
\<\/tr\>",
         RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);

        public static IEnumerable<MStatus> GetTimeline(Account a, TimelineTypes type)
        {
            #region Request and download
            HttpWebRequest req = null;
            switch (type)
            {
                case TimelineTypes.Timeline:
                    //TL:http://mixi.jp/recent_echo.pl
                    req = nc.CreateRequest(new Uri("http://mixi.jp/recent_echo.pl"), false);
                    break;
                case TimelineTypes.MyVoice:
                    //My:http://mixi.jp/list_echo.pl
                    req = nc.CreateRequest(new Uri("http://mixi.jp/list_echo.pl"), false);
                    break;
                case TimelineTypes.Replies:
                    //Re:http://mixi.jp/res_echo.pl
                    req = nc.CreateRequest(new Uri("http://mixi.jp/res_echo.pl"), false);
                    break;
                default:
                    throw new ArgumentOutOfRangeException("type");
            }
            var ret = nc.WebConnect<string>(req, "GET", null,
                NetConnect.DefaultStreamReaders.ReadStringByStream, null);
            if (!ret.Succeeded)
                yield break;
            #endregion
            var matches = mixiAnalyzer.Matches(ret.Data);
            if (matches.Count == 0)
                yield break;
            for (int msi = 0; msi < matches.Count; msi++)
            {
                var match = matches[msi];
                if(match.Groups["UserId"] == null)
                    continue;
                var user = Kernel.Storage.LookupUser(match.Groups["UserId"].Value);
                if (user == null)
                {
                    user = new MUser();
                    user.IconUri = new Uri(match.Groups["Icon"].Value);
                    user.Id = match.Groups["UserId"].Value;
                    user.Name = match.Groups["UserName"].Value;
                    user.Protected = false;
                    Kernel.Storage.RegistUser(user);
                }
                var ms = new MStatus();
                ms.User = user;
                ms.Id = match.Groups["Permalink"].Value;
                long createdAt;
                if(long.TryParse(match.Groups["CreatedAt"].Value, out createdAt))
                    continue;
                ms.CreatedAt = UnixEpoch.GetDateTimeByUnixEpoch(createdAt);
                ms.Text = new Krile.Kernel.Control.XString();
                ms.Text = ms.Text.Original.CreateXString(match.Groups["Body"].Value);
                yield return ms;
            }
            yield break;
        }
    }
}
